package top.blackr.folivora.common.security.crud.repository;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.repository.CrudRepository;
import lombok.AllArgsConstructor;
import net.dreamlu.mica.core.utils.BeanUtil;
import org.springframework.stereotype.Component;
import top.blackr.folivora.common.core.enums.ResultEnum;
import top.blackr.folivora.common.core.exception.BizException;
import top.blackr.folivora.common.security.crud.mapper.SysRoleMapper;
import top.blackr.folivora.common.security.crud.model.entity.SysRole;
import top.blackr.folivora.common.security.crud.model.entity.SysRoleMenu;
import top.blackr.folivora.common.security.crud.model.vo.SysRoleVo;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Component
@AllArgsConstructor
public class SysRoleRepository extends CrudRepository<SysRoleMapper, SysRole> {

    private final SysRoleMenuRepository sysRoleMenuRepository;

    public Page<SysRoleVo> roleInfoPage(Page<SysRole> page, SysRoleVo params) {
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotEmpty(params.getRoleName())) {
            wrapper.eq(SysRole::getRoleName, params.getRoleName());
        }
        if (StrUtil.isNotEmpty(params.getRoleCode())) {
            wrapper.eq(SysRole::getRoleCode, params.getRoleCode());
        }
        wrapper.eq(SysRole::getDelFlag, 0);
        wrapper.select(SysRole::getRoleId, SysRole::getRoleName,
                SysRole::getRoleCode, SysRole::getRoleDesc,
                SysRole::getCreateTime);
        page = this.page(page, wrapper);
        List<SysRole> records = page.getRecords();
        List<SysRoleVo> sysRoleVos = BeanUtil.copyProperties(records, SysRoleVo.class);
        Page<SysRoleVo> result = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        result.setRecords(sysRoleVos);
        return result;
    }

    public Boolean saveRole(SysRoleVo sysRoleVo) {
        SysRole sysRole = BeanUtil.copyProperties(sysRoleVo, SysRole.class);
        long count = this.count(new LambdaQueryWrapper<SysRole>().eq(SysRole::getRoleCode, sysRoleVo.getRoleCode()));
        // roleCode不能重复
        if (count >= 1) {
            throw new BizException(ResultEnum.FAIL);
        }
        return this.save(sysRole);
    }

    public Boolean updateRole(SysRoleVo sysRoleVo) {
        SysRole sysRole = BeanUtil.copyProperties(sysRoleVo, SysRole.class);
        sysRole.setRoleCode(null);
        return this.updateById(sysRole);
    }

    public Boolean delRole(SysRoleVo sysRoleVo) {
        return this.removeById(sysRoleVo.getRoleId());
    }

    public Boolean relationMenus(SysRoleVo params) {
        Integer roleId = params.getRoleId();
        Set<Integer> menus = params.getMenus();
        Set<SysRoleMenu> roleMenus = menus.stream().map(menuId -> {
            SysRoleMenu roleMenu = new SysRoleMenu();
            roleMenu.setRoleId(roleId);
            roleMenu.setMenuId(menuId);
            return roleMenu;
        }).collect(Collectors.toSet());
        // 先删除老数据
        sysRoleMenuRepository.remove(Wrappers.<SysRoleMenu>lambdaQuery().eq(SysRoleMenu::getRoleId, roleId));
        // 保存角色菜单关联关系
        return sysRoleMenuRepository.saveBatch(roleMenus, roleMenus.size());
    }

    public Set<SysRoleVo> getRolesByUserId(Long userId) {
        return baseMapper.getRolesByUserId(userId);
    }
}
